#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdio>
#include <cstring>
#include <cassert>
using namespace std;

#define N 2
#define NUM 1024
void Writer(int wid)
{
    char buffer[NUM];
    string str = "I am a child process";
    pid_t id = getpid();
    int number = 0;
    while (1)
    {
        buffer[0] = 0; // 清空缓冲区？  当成字符串了
        // 限制大小的向指定文件中进行格式化输出
        snprintf(buffer, sizeof(buffer), "%s %d %d", str.c_str(), id, number++);
        // cout<<buffer<<endl;
        ssize_t n=write(wid,buffer,strlen(buffer));
        sleep(1);
        //写入一个字符
        // char c='c';
        // ssize_t n = write(wid, &c, 1); // 通过系统调用接口向文件缓冲区写入
        // cout<<number<<endl;
        // if(number>5) break;
        // sleep(1);
    }
}
void Reader(int rid)
{
    char buffer[NUM];
    int cnt=0;
    while (cnt<5)
    {
        //sleep(10);
        buffer[0]=0;
        ssize_t n = read(rid, buffer, sizeof(buffer));
        if(n>0)
        {
            buffer[n]=0;
            cout<<"I am parent pid="<<getpid()<<" get message:"<<buffer<<endl;
        }
        cnt++;
        //cout<<"n: "<<n<<endl;
    }
}
int main()
{
    int pipefd[N];
    int n = pipe(pipefd);
    if (n < 0)
        return 1;
    else
    {
        // cout<<"pipefd[0]="<<pipefd[0]<<" pipefd[1]="<<pipefd[1]<<endl;
        pid_t id = fork();
        if (id < 0)
            return 2;
        else if (id == 0)
        {
            // child
            close(pipefd[0]); // 关闭读端
            Writer(pipefd[1]);

            close(pipefd[1]); // 结束时关闭  可有可无
            exit(0);
        }
        // child-->w  parent-->r
        // parent
        close(pipefd[1]); // 关闭写端
        Reader(pipefd[0]);
        cout<<"读端结束，关闭读端！"<<endl;
        close(pipefd[0]); // 结束时关闭
        sleep(2);
        int statu=0;
        pid_t wid = waitpid(id, &statu, 0);
        //assert(!wid);
        cout<<"wid= "<<wid<<endl;
        cout<<"wait success pid="<<getpid()<<" exit code: "<<((statu>>8)&0xff)<<"exit signal: "<<(statu&0x7f)<<endl;
        sleep(3);
 
    }
    return 0;
}
